home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / ccr.zip / CCR-ITEM.T < prev    next >
Text File  |  1993-01-23  |  28KB  |  1,137 lines

  1. /*
  2.  * Colossal Cave Revisited
  3.  *
  4.  * A remake of Willie Crowther and Don Woods' classic Adventure.
  5.  * Converted from Donald Ekman's PC port of the original FORTRAN source.
  6.  * TADS version by David M. Baggett for ADVENTIONS.
  7.  *
  8.  * Please document all changes in the history so we know who did what.
  9.  *
  10.  * This source code is copylefted under the terms of the GNU Public
  11.  * License.  Essentially, this means that you are free to do whatever
  12.  * you wish with this source code, provided you do not charge any
  13.  * money for it or for any derivative works.
  14.  *
  15.  * ADVENTIONS distributes this game, but you are free to do what you will
  16.  * with it, provided you adhere to the terms in the GNU Public License.
  17.  * Send correspondence regarding this game or original works distributed
  18.  * by ADVENTIONS to 
  19.  *
  20.  *    ADVENTIONS
  21.  *    PO Box 851
  22.  *    Columbia, MD 21044 USA
  23.  *
  24.  * If you would like a catalog of releases, please enclose a SASE.  Thanks!
  25.  *
  26.  * Contributors
  27.  *
  28.  *    dmb    In real life:    David M. Baggett
  29.  *        Internet:    <dmb@ai.mit.edu>
  30.  *        Compu$erve:    76440,2671 (ADVENTIONS account)
  31.  *        GEnie:        ADVENTIONS
  32.  *
  33.  * Modification History
  34.  *
  35.  * 1-Jan-93    dmb    rec.arts.int-fiction BETA release (source only)
  36.  *                      For beta testing only -- not for general
  37.  *            distribution.
  38.  *
  39.  */
  40.  
  41. /*
  42.  * This file defines all carryable items in the game.
  43.  */
  44. class CCR_item: item;
  45.  
  46. /*
  47.  * Important notes about treasures:
  48.  *
  49.  * Every treasure must have istreasure set to true; likewise, only
  50.  * treasures should have this set.  The code in preinit that determines
  51.  * the number of treasures the player has yet to find relies on this.
  52.  *
  53.  * If you want to add treasures, use the CCR_treasure_item class.  Take
  54.  * care to call pass doDrop and pass doTake if you override the doDrop
  55.  * or doTake methods, because it is in these methods that the scoing
  56.  * is handled.
  57.  *
  58.  * Each treasure is worth self.takepoints points when taken for the
  59.  * first time, and an additional self.depositpoints when deposited
  60.  * in the bulding.  Be sure to update global.maxscore and scoreRank
  61.  * if you add treasures (or anything else that gives the player points,
  62.  * for that matter).
  63.  */
  64. class CCR_treasure_item: CCR_item
  65.     istreasure = true
  66.  
  67.     plural = 'treasures' 'goodies' 'loot'
  68.  
  69.     takepoints = 2        // points for taking this treasure
  70.     depositpoints = 12    // points for putting in building
  71.  
  72.     awardedpointsfortaking = nil
  73.     awardedpointsfordepositing = nil
  74.     
  75.     doTake(actor) = {
  76.         //
  77.         // Give the player some points for taking the treasure
  78.         // the first time.
  79.         //
  80.         // If the player removes a treasure from the bulding
  81.         // floor, reduce his score by the value of that
  82.         // treasure.  (This is to prevent him from dropping
  83.         // a treasure off, getting the points, and then giving
  84.         // it to the troll or otherwise losing it.) 
  85.         //
  86.         if (not self.awardedpointsfortaking) {
  87.             incscore(self.takepoints);
  88.             self.awardedpointsfortaking := true;
  89.         }
  90.         if (self.awardedpointsfordepositing) {
  91.             if (self.isIn(Inside_Building)) {
  92.                 incscore(-1 * self.depositpoints);
  93.                 self.awardedpointsfordepositing := nil;
  94.  
  95.                 // That's one more treasure to deposit.
  96.                 global.treasures := global.treasures + 1;
  97.             }
  98.         }
  99.         
  100.         pass doTake;
  101.     }
  102.     doDrop(actor) = {
  103.         self.checkpoints;
  104.         pass doDrop;
  105.     }
  106.  
  107.     checkpoints = {
  108.         //
  109.         // Award points for putting treasure in building (unless
  110.         // we've already awarded the points for depositing this
  111.         // treasure).
  112.         //
  113.         if (Me.isIn(Inside_Building)) {
  114.             if (not self.awardedpointsfortaking) {
  115.                 //
  116.                 // This shouldn't happen, but just in case...
  117.                 //
  118.                 incscore(self.takepoints);
  119.                 self.awardedpointsfortaking := true;
  120.             }
  121.             else if (not self.awardedpointsfordepositing) {
  122.                 incscore(self.depositpoints);
  123.                 self.awardedpointsfordepositing := true;
  124.  
  125.                 // That's one less treasure to deposit.
  126.                 global.treasures := global.treasures - 1;
  127.             } 
  128.         }
  129.     }
  130. ;
  131.  
  132. set_of_keys: CCR_item, keyItem
  133.     sdesc = "set of keys"
  134.     ldesc = "It's just a normal-looking set of keys."
  135.     location = Inside_Building
  136.     noun = 'keys' 'key' 'keyring' 'set'
  137.     adjective = 'key'
  138. ;
  139.  
  140. brass_lantern: CCR_item, lightsource
  141.     turnsleft = 330        // expert mode (default)
  142.     sdesc = "brass lantern"
  143.     ldesc = {
  144.         "It is a shiny brass lamp";
  145.  
  146.         if (self.islit) {
  147.             if (self.turnsleft <= 30)
  148.                 ", glowing dimly.";
  149.             else
  150.                 ", glowing brightly.";
  151.         }
  152.         else
  153.             ".  It is not currently lit.";
  154.     }
  155.     location = Inside_Building
  156.     noun = 'lamp' 'headlamp' 'headlight' 'lantern' 'light'
  157.  
  158.     ison = nil
  159.     islit = {
  160.         if (self.ison and self.turnsleft > 0)
  161.             return true;
  162.         else
  163.             return nil;
  164.     }    
  165.     
  166.     verDoRub(actor) = {}
  167.     doRub(actor) = {
  168.         "Rubbing the electric lamp is not particularly 
  169.         rewarding.  Anyway, nothing exciting happens.";
  170.     }
  171.  
  172.     verDoTurnon(actor) = {
  173.         if (self.ison)
  174.             "It's already on.";
  175.     }
  176.     doTurnon(actor) = {
  177.         "The lamp is now on.";
  178.         self.ison := true;
  179.  
  180.         if (self.turnsleft > 0)
  181.             notify(self, &wearbatteries, 0);
  182.         else
  183.             "  Unfortunately, the batteries seem to
  184.             be dead.";
  185.     }
  186.     verDoTurnoff(actor) = {
  187.         if (not self.ison)
  188.             "It's already off.";
  189.     }
  190.     doTurnoff(actor) = {
  191.         "The lamp is now off.";
  192.         self.turnoff;
  193.     }
  194.     verDoLight(actor) = { self.verDoTurnon(actor); }
  195.     doLight(actor) = { self.doTurnon(actor); }
  196.  
  197.     verIoPutIn(actor) = {}
  198.     ioPutIn(actor, dobj) = {
  199.         if (dobj = old_batteries)
  200.             "Those batteries are dead; they won't
  201.             do any good at all.";
  202.         else if (dobj = fresh_batteries)
  203.             self.do_replace;
  204.         else
  205.             "The only thing you might successfully put in 
  206.             the lamp is a fresh pair of batteries.";
  207.     }
  208.  
  209.     // The following method is called when the player gets resurrected.
  210.     turnoff = {
  211.         if (self.ison) {
  212.             self.ison := nil;
  213.             unnotify(self, &wearbatteries);
  214.         }
  215.     }
  216.  
  217.     wearbatteries = {
  218.         self.turnsleft := self.turnsleft - 1;
  219.  
  220.         if (self.turnsleft < 1) {
  221.             P(); I();
  222.             "Your lamp has run out of power. ";
  223.  
  224.             if (self.replace_batteries) {
  225.                 // do nothing
  226.             }
  227.             else if (Me.location.isoutside) {
  228.                 "There's not much point in wandering 
  229.                 around out here, and you can't 
  230.                 explore the cave without a lamp. So 
  231.                 let's just call it a day.";
  232.  
  233.                 call_it_a_day();
  234.             }
  235.         }
  236.         else if (self.turnsleft = 30) {
  237.             P(); I();
  238.             "Your lamp is getting dim. ";
  239.  
  240.             if (self.replace_batteries) {
  241.                 // do nothing.
  242.             }
  243.             else if (fresh_batteries.used) {
  244.                 // DMB: changed the wording of this
  245.                 // slightly for convenience.
  246.                 "You're also out of spare batteries.  
  247.                 You'd best start wrapping this up.";
  248.             }
  249.             else if (fresh_batteries.location <> nil) {
  250.                 "You'd best go back for those 
  251.                 batteries.";
  252.             }
  253.             else {
  254.                 "You'd best start wrapping this up, 
  255.                 unless you can find some fresh 
  256.                 batteries. I seem to recall there's a 
  257.                 vending machine in the maze.  Bring 
  258.                 some coins with you.";
  259.             }
  260.         }
  261.     }
  262.  
  263.     replace_batteries = {
  264.         if (fresh_batteries.isIn(Me.location)) {
  265.             " I'm taking the liberty of replacing the
  266.             batteries.";
  267.  
  268.             self.do_replace;
  269.  
  270.             return true;
  271.         }
  272.         else
  273.             return nil;
  274.     }
  275.  
  276.     do_replace = {
  277.         fresh_batteries.used := true;
  278.         fresh_batteries.moveInto(nil);
  279.         old_batteries.moveInto(Me.location);
  280.         self.turnsleft := 2500;
  281.     }
  282. ;
  283.  
  284. black_rod: CCR_item
  285.     sdesc = "black rod"
  286.     ldesc = "It's a three foot black rod with a rusty star on an end."
  287.     location = In_Debris_Room
  288.     noun = 'rod' 'star'
  289.     adjective = 'black' 'rusty' 'star'
  290.  
  291.     verDoWave(actor) = {}
  292.     doWave(actor) = {
  293.         if (self.isIn(West_Side_Of_Fissure) or
  294.             self.isIn(On_East_Bank_Of_Fissure)) {
  295.  
  296.             if (global.closed) {
  297.                 "Peculiar.  Nothing happens.";
  298.             }
  299.             else {
  300.                 if (CrystalBridge.exists) {
  301.                     "The crystal bridge has 
  302.                     vanished!";
  303.                     CrystalBridge.exists := nil;
  304.                 }
  305.                 else {
  306.                     "A crystal bridge now spans 
  307.                     the fissure.";
  308.                     CrystalBridge.exists := true;
  309.                 }
  310.             }
  311.         }
  312.         else
  313.             "Nothing happens.";
  314.     }
  315. ;
  316.  
  317. wicker_cage: CCR_item, container
  318.     sdesc = "wicker cage"
  319.     ldesc = {
  320.         "It's a small wicker cage.";
  321.     }
  322.     location = In_Cobble_Crawl
  323.     noun = 'cage'
  324.     adjective = 'small' 'wicker' 'bird'
  325.  
  326.     verDoPutIn(actor) = {}
  327.     doPutIn(actor, io) = {
  328.         if (io <> little_bird) {
  329.             caps(); self.thedesc; " isn't big enough
  330.             to hold "; io.thedesc; ".";
  331.         }
  332.         else
  333.             pass doPutIn;
  334.     }
  335. ;
  336.  
  337. /*
  338.  * The following rod is actually an explosive.  Don't ask ME how anyone
  339.  * is supposed to figure this out from the description.  I've left it
  340.  * the way it was even though I think it's pretty bogus.
  341.  *
  342.  * I've added the words 'explosive' and 'dynamite' as nouns and adjectives,
  343.  * and 'blast' as an adjective.  Perhaps this will give some lucky soul
  344.  * a clue.
  345.  */
  346. black_mark_rod: CCR_item
  347.     sdesc = "marked rod"
  348.     ldesc = {
  349.         "It's a three foot black rod with a rusty mark on an end.";
  350.     }
  351.     location = At_Sw_End
  352.     noun = 'rod' 'mark' 'explosive' 'dynamite'
  353.     adjective = 'black' 'rusty' 'mark' 'blast' 'explosive' 'dynamite'
  354.  
  355.     verDoWave(actor) = {}
  356.     doWave(actor) = { "Nothing happens."; }
  357.  
  358.     verDoBlastWith(actor) = {}
  359.     doBlastWith(actor) = { endpuzzle(); }
  360. ;
  361.  
  362. little_bird: CCR_item
  363.     sdesc = {
  364.         if (not self.isIn(wicker_cage))
  365.             "cheerful ";
  366.         
  367.         "little bird";
  368.     }
  369.     ldesc = {
  370.         if (self.isIn(wicker_cage))
  371.             "The little bird looks unhappy in the cage.";
  372.         else
  373.             "The cheerful little bird is sitting here singing.";
  374.     }
  375.     location = In_Bird_Chamber
  376.     noun = 'bird'
  377.  
  378.     verDoFeed(actor) = {}
  379.     doFeed(actor) = {
  380.         "It's not hungry. (It's merely pinin' for the fjords). 
  381.          Besides, you have no bird seed.";
  382.     }
  383.     verIoGiveTo(actor) = {
  384.         "I suspect it would prefer bird seed.";
  385.     }
  386.  
  387.     /*
  388.      * Catch any attempt to remove the bird.  It won't cooperate
  389.      * When the player has the rod with the star on the end.
  390.      */
  391.     verifyRemove(actor) = {
  392.         if (self.isIn(Me)) {
  393.             "You already have the little bird.  If
  394.             you take it out of the cage it will likely
  395.             fly away from you.";
  396.         }
  397.         else if (black_rod.isIn(Me)) {
  398.             "The bird was unafraid when you entered, but 
  399.             as you approach it becomes disturbed and you 
  400.             cannot catch it.";
  401.         }
  402.         else
  403.             pass verifyRemove;
  404.     }
  405.  
  406.     verDoTake(actor) = {
  407.         if (not wicker_cage.isIn(Me))
  408.             "You can catch the bird, but you cannot carry it.";
  409.         else
  410.             pass verDoTake;
  411.     }
  412.     doTake(actor) = {
  413.         self.doPutIn(Me, wicker_cage);
  414.     }
  415.  
  416.     verDoPutIn(actor) = {}
  417.     doPutIn(actor, io) = {
  418.         if (io <> wicker_cage) {
  419.             "Don't put the poor bird in "; io.thedesc; "!";
  420.         }
  421.         else
  422.             pass doPutIn;
  423.     }
  424.  
  425.     verDoAttack(actor) = {
  426.         if (self.isIn(wicker_cage)) 
  427.             "Oh, leave the poor unhappy bird alone.";
  428.         else {
  429.             "The little bird is now dead.  Its body disappears.";
  430.             self.moveInto(nil);
  431.         }
  432.     }
  433.  
  434.     verDoDrop(actor) = {}
  435.     doDrop(actor) = {
  436.         if (self.isIn(Snake.location)) {
  437.             "The little bird attacks the green snake, and 
  438.             in an astounding flurry drives the snake 
  439.             away.";
  440.  
  441.             Snake.moveInto(nil);
  442.             self.moveInto(Me.location);
  443.         }
  444.         else if (self.isIn(Dragon.location)) {
  445.             "The little bird attacks the green dragon, 
  446.             and in an astounding flurry gets burnt to a 
  447.             cinder.  The ashes blow away.";
  448.  
  449.             self.moveInto(nil);
  450.         }
  451.         else
  452.             pass doDrop;
  453.     }
  454.  
  455.     doTakeOut(actor, io) = {
  456.         // Drop ourselves automatically.  (The bird flies away
  457.         // when taken out of a container.)
  458.         self.doDrop(actor);
  459.     }
  460. ;
  461.  
  462. velvet_pillow: CCR_item
  463.     sdesc = "velvet pillow"
  464.     ldesc = "It's just a small velvet pillow."
  465.     location = In_Soft_Room
  466.     noun = 'pillow'
  467.     adjective = 'velvet' 'small'
  468. ;
  469.  
  470. giant_bivalve: CCR_item
  471.     opened = nil
  472.  
  473.     sdesc = {
  474.         if (self.opened)
  475.             "giant oyster";
  476.         else
  477.             "giant clam";
  478.  
  479.         if (self.isIn(Me))
  480.             " >grunt!<";
  481.     }
  482.     thedesc = {
  483.         if (self.opened)
  484.             "the giant oyster";
  485.         else
  486.             "the giant clam";
  487.     }
  488.     
  489.     ldesc = {
  490.         "It's an enormous clam with its shell tightly closed.";
  491.  
  492.         // During the endgame, the oyster has something
  493.         // written on it.
  494.         if (self.isIn(At_Ne_End) or self.isIn(At_Sw_End)) {
  495.             "Interesting.  There seems to be something 
  496.             written on the underside of the oyster.";
  497.         }
  498.     }
  499.     location = In_Shell_Room
  500.     noun = 'clam' 'oyster' 'bivalve' 'shell'
  501.     adjective = 'giant' 'enormous' 'massive' 'big' 'huge' 'tightly'
  502.         'closed' 'five' 'foot' 'five-foot' '5-foot'
  503.  
  504.     verDoOpen(actor) = { self.verDoOpenWith(actor, nil); }
  505.     doOpen(actor) = {
  506.         if (trident.isIn(Me)) {
  507.             //
  508.             // In the original, "open clam" would work
  509.             // ask long as you were carrying the trident,
  510.             // but this seems very prone to accidental
  511.             // solving, and since we aren't limited to
  512.             // two word parsing, I've just taken the
  513.             // liberty of forcing the player to type
  514.             // "open clam with trident."
  515.             //
  516.             "You'll need to be a bit more specific that 
  517.             that, I'm afraid.";
  518.         }
  519.         else {
  520.             "You don't have anything strong enough to 
  521.             open "; self.thedesc; ".";
  522.         }
  523.     }
  524.     verDoOpenWith(actor, io) = {
  525.         if (self.isIn(Me)) {
  526.             "I advise you to put down "; self.thedesc;
  527.             " before opening it.  >Strain!<";
  528.         }
  529.     }
  530.     doOpenWith(actor, io) = {
  531.         if (io = trident) {
  532.             if (self.opened) {
  533.                 "The oyster creaks open, revealing nothing 
  534.                 but oyster inside.  It promptly snaps shut 
  535.                 again.";  
  536.             }
  537.             else {
  538.                 "A glistening pearl falls out of the clam and 
  539.                 rolls away.  Goodness, this must really be an 
  540.                 oyster.  (I never was very good at 
  541.                 identifying bivalves.)  Whatever it is, it 
  542.                 has now snapped shut again.";
  543.  
  544.                 self.opened := true;
  545.                 pearl.moveInto(In_A_Cul_De_Sac);
  546.             }
  547.         }
  548.         else {
  549.             caps(); io.thedesc; " isn't strong enough to 
  550.             open "; self.thedesc; ".";
  551.         }
  552.     }
  553.     verDoBreak(actor) = {
  554.         "The shell is very strong and is impervious to 
  555.         attack.";
  556.     }
  557.     verDoAttack(actor) = { self.verDoBreak(actor); }
  558.     verDoAttackWith(actor, io) = { self.verDoBreak(actor); }
  559.  
  560.     //
  561.     // The oyster has a hint written on its underside once
  562.     // the cave's closed.  (Look, don't ask me, I'm just
  563.     // porting this game!)
  564.     //
  565.     verDoRead(actor) = {
  566.         if (not self.isIn(At_Ne_End) and not self.isIn(At_Sw_End))
  567.             "You're babbling -- snap out of it!";
  568.     }
  569.     doRead(actor) = {
  570.         //
  571.         // This is supposed to be a hint (i.e., it's supposed
  572.         // to cost points), but I've put it in as a freebie
  573.         // because I think the final puzzle is absurdly
  574.         // difficult even with the free hint.
  575.         //
  576.         "It says, \"There is something strange about this 
  577.         place, such that one of the words I've always known 
  578.         now has a new effect.\"";
  579.     }
  580. ;
  581.  
  582. spelunker_today: CCR_item, readable
  583.     sdesc = "recent issues of \"Spelunker Today\""
  584.     adesc = { self.sdesc; }
  585.     ldesc = { self.readdesc; }
  586.     readdesc = {
  587.         // This said "magazine is written" in the original,
  588.         // which is obviously wrong given the sdesc.
  589.  
  590.         "I'm afraid the magazines are written in Dwarvish.";
  591.     }
  592.  
  593.     location = In_Anteroom
  594.     plural = 'magazines'
  595.     noun = 'magazine' 'issue' 'issue' 'spelunker'
  596.         'today' 'dwarvish'
  597.     adjective = 'spelunker' 'today' 'dwarvish'
  598.  
  599.     doDrop(actor) = {
  600.         if (Me.isIn(At_Witts_End))
  601.             silent_incscore(global.wittpoints);
  602.  
  603.         pass doDrop;
  604.     }
  605.     doTake(actor) = {
  606.         if (Me.isIn(At_Witts_End))
  607.             silent_incscore(-1 * global.wittpoints);
  608.  
  609.         pass doTake;
  610.     }
  611. ;
  612.  
  613. tasty_food: CCR_item, fooditem
  614.     sdesc = "some tasty food"
  615.     adesc = { self.sdesc; }
  616.     thedesc = "the tasty food"
  617.     ldesc = "Sure looks yummy!"
  618.     location = Inside_Building
  619.     noun = 'food' 'ration' 'rations' 'tripe'
  620.     adjective = 'yummy' 'tasty' 'delicious' 'scrumptious'
  621. ;
  622.  
  623. bottle: CCR_item
  624.     haswater = true
  625.     hasoil = nil
  626.  
  627.     sdesc = {
  628.         if (self.haswater)
  629.             "small bottle of water";
  630.         else if (self.hasoil)
  631.             "small bottle of oil";
  632.         else
  633.             "small empty bottle";
  634.     }
  635.     location = Inside_Building
  636.     noun = 'bottle' 'jar' 'flask'
  637.  
  638.     verIoPutIn(actor) = {}
  639.     ioPutIn(actor, dobj) = {
  640.         if (self.haswater)
  641.             "The bottle is already full of water.";
  642.         else if (self.hasoil)
  643.             "The bottle is already full of oil.";
  644.         else if (dobj = Stream) {
  645.             "The bottle is now full of water.";
  646.             self.haswater := true;
  647.         }
  648.         else if (dobj = Oil) {
  649.             "The bottle is now full of oil.";
  650.             self.hasoil := true;
  651.         }
  652.         else {
  653.             "I'm not sure how to do that.";
  654.         }
  655.     }
  656.  
  657.     verDoFill(actor) = {}
  658.     doFill(actor) = {
  659.         if (self.isIn(Stream.location))
  660.             self.ioPutIn(actor, Stream);
  661.         else if (self.isIn(Oil.location))
  662.             self.ioPutIn(actor, Oil);
  663.         else
  664.             "There is nothing here with which to fill the 
  665.             bottle.";
  666.     }
  667.  
  668.     verDoEmpty(actor) = {}
  669.     doEmpty(actor) = {
  670.         if (self.haswater or self.hasoil)
  671.             "Your bottle is now empty and the ground is 
  672.             now wet.";
  673.         else
  674.             "The bottle is already empty!";
  675.  
  676.         self.empty;
  677.     }
  678.  
  679.     verDoPourOn(actor, io) = {}
  680.     doPourOn(actor, io) = {
  681.         if (io = RustyDoor) {
  682.             if (self.hasoil) {
  683.                 "The oil has freed up the hinges so that the 
  684.                 door will now move, although it requires some 
  685.                 effort.";
  686.  
  687.                 RustyDoor.isoiled := true;
  688.             }
  689.             else if (self.haswater) {
  690.                 "The hinges are quite thoroughly 
  691.                 rusted now and won't budge.";
  692.             }
  693.             else {
  694.                 "The bottle is empty.";
  695.             }
  696.  
  697.             self.empty;
  698.         }
  699.         else if (io = Plant) {
  700.             if (self.haswater) {
  701.                 Plant.water;
  702.             }
  703.             else if (self.hasoil) {
  704.                 "The plant indignantly shakes the oil 
  705.                 off its leaves and asks, \"Water?\"";
  706.             }
  707.             else {
  708.                 "The bottle is empty.";
  709.             }
  710.  
  711.             self.empty;
  712.         }
  713.         else if (io = theFloor)
  714.             self.doEmpty(actor);
  715.         else
  716.             "That doesn't seem productive.";
  717.     }
  718.  
  719.     verDoDrink(actor) = {
  720.         if (not self.hasoil and not self.haswater)
  721.             "The bottle is empty.";
  722.  
  723.         if (self.hasoil)
  724.             "Don't drink the oil, you fool!";
  725.     }
  726.     doDrink(actor) = {
  727.         "The bottle is now empty.";
  728.         self.empty;
  729.     }
  730.  
  731.     empty = {
  732.         self.haswater := nil;
  733.         self.hasoil := nil;
  734.     }
  735. ;
  736. water_in_the_bottle: CCR_decoration
  737.     sdesc = "water in the bottle"
  738.     adesc = "water"
  739.     ldesc = "It looks like ordinary water to me."
  740.     locationOK = true    // tell compiler OK for location to be method
  741.     location = {
  742.         if (bottle.haswater)
  743.             return bottle.location;
  744.         else
  745.             return nil;
  746.     }
  747.     noun = 'water' 'h2o'
  748.  
  749.     verDoPourOn(actor, io) = {}
  750.     doPourOn(actor, io) = { bottle.doPourOn(actor, io); }
  751.     verDoDrink(actor) = { bottle.verDoDrink(actor); }
  752.     doDrink(actor) = { bottle.doDrink(actor); }
  753. ;
  754. oil_in_the_bottle: CCR_decoration
  755.     sdesc = "oil in the bottle"
  756.     adesc = "oil"
  757.     ldesc = "It looks like ordinary oil to me."
  758.     locationOK = true    // tell compiler OK for location to be method
  759.     location = {
  760.         if (bottle.hasoil)
  761.             return bottle.location;
  762.         else
  763.             return nil;
  764.     }
  765.     noun = 'oil' 'lubricant' 'grease'
  766.  
  767.     verDoPourOn(actor, io) = {}
  768.     doPourOn(actor, io) = { bottle.doPourOn(actor, io); }
  769.     verDoDrink(actor) = { bottle.verDoDrink(actor); }
  770.     doDrink(actor) = { bottle.doDrink(actor); }
  771. ;
  772.  
  773. axe: CCR_item
  774.     nograb = nil    // hack for when you attack the bear with it
  775.  
  776.     sdesc = "dwarf's axe"
  777.     ldesc = {
  778.         if (self.nograb)
  779.             "It's lying beside the bear.";
  780.         else
  781.             "It's just a little axe.";
  782.     }
  783.     location = nil        // created when first dwarf attacks
  784.     noun = 'axe'
  785.     adjective = 'little' 'dwarf' 'dwarvish' 'dwarven' 'dwarf\'s'
  786.  
  787.     verifyRemove(actor) = {
  788.         if (self.nograb)
  789.             "No chance.  It's lying beside the ferocious 
  790.             bear, quite within harm's way.";
  791.     }
  792. ;
  793.  
  794. fresh_batteries: CCR_item
  795.     used = nil    // used in lamp yet?
  796.  
  797.     sdesc = "fresh batteries"
  798.     ldesc = {
  799.         "They look like ordinary batteries.  (A sepulchral 
  800.         voice says, \"Still going!\")";
  801.     }
  802.     noun = 'batteries' 'battery' 'duracel' 'duracell' 'duracels'
  803.         'duracells' 'energizer' 'energizers' 'everready'
  804.         'everreadies' 'eveready' 'evereadies'
  805.     adjective = 'fresh'
  806.  
  807.     location = nil
  808. ;
  809.  
  810. old_batteries: CCR_item
  811.     sdesc = "worn-out batteries"
  812.     ldesc = {
  813.         "They look like ordinary batteries.";
  814.     }
  815.     noun = 'batteries' 'battery' 'duracel' 'duracell' 'duracels'
  816.         'duracells' 'energizer' 'energizers' 'everready'
  817.         'everreadies' 'eveready' 'evereadies'
  818.     adjective = 'worn' 'out' 'worn-out' 'dead' 'empty' 'dry' 'old'
  819.  
  820.     location = nil
  821. ;
  822.  
  823. /*
  824.  * Treasures
  825.  */
  826. large_gold_nugget: CCR_treasure_item
  827.     depositpoints = 10
  828.     sdesc = "large gold nugget"
  829.     ldesc = "It's a large sparkling nugget of gold!"
  830.     location = In_Nugget_Of_Gold_Room
  831.     noun = 'gold' 'nugget'
  832.     adjective = 'gold' 'large'
  833. ;
  834. several_diamonds: CCR_treasure_item
  835.     depositpoints = 10
  836.     sdesc = "several diamonds"
  837.     adesc = { self.sdesc; }
  838.     thedesc = "the diamonds"
  839.     ldesc = "They look to be of the highest quality!"
  840.     location = West_Side_Of_Fissure
  841.     noun = 'diamond' 'diamonds'
  842.     adjective = 'several' 'high' 'quality' 'high-quality'
  843. ;
  844. bars_of_silver: CCR_treasure_item
  845.     depositpoints = 10
  846.     sdesc = "bars of silver"
  847.     adesc = { self.sdesc; }
  848.     ldesc = "They're probably worth a fortune!"
  849.     location = Low_N_S_Passage
  850.     noun = 'silver' 'bars'
  851.     adjective = 'silver'
  852. ;
  853. precious_jewelry: CCR_treasure_item
  854.     depositpoints = 10
  855.     sdesc = "precious jewelry"
  856.     adesc = { self.sdesc; }
  857.     ldesc = "It's all quite exquisite!"
  858.     location = In_South_Side_Chamber
  859.     noun = 'jewel' 'jewels' 'jewelry'
  860.     adjective = 'precious' 'exquisite'
  861. ;
  862. rare_coins: CCR_treasure_item
  863.     depositpoints = 10
  864.     sdesc = "rare coins"
  865.     adesc = { self.sdesc; }
  866.     ldesc = "They're a numismatist's dream!"
  867.     location = In_West_Side_Chamber
  868.     noun = 'coins'
  869.     adjective = 'rare'
  870. ;
  871. treasure_chest: CCR_treasure_item
  872.     spotted = nil    // found yet?  See also Dead_End_13 in ccr-room.t
  873.  
  874.     depositpoints = 12
  875.     sdesc = "treasure chest"
  876.     ldesc = {
  877.         "It's the pirate's treasure chest, filled with
  878.         riches of all kinds!";
  879.     }
  880.     location = nil
  881.     noun = 'chest' 'box' 'treasure' 'riches'
  882.     adjective = 'pirate' 'pirate\'s' 'treasure'     
  883. ;
  884. golden_eggs: CCR_treasure_item
  885.     depositpoints = 14
  886.     sdesc = "nest of golden eggs"
  887.     ldesc = "The nest is filled with beautiful golden eggs!"
  888.     location = In_Giant_Room
  889.     noun = 'eggs' 'egg' 'nest'
  890.     adjective = 'golden' 'beautiful'
  891. ;
  892. trident: CCR_treasure_item
  893.     depositpoints = 14
  894.     sdesc = "jeweled trident"
  895.     ldesc = "The trident is covered with fabulous jewels!"
  896.     location = In_Cavern_With_Waterfall
  897.     noun = 'trident'
  898.     adjective = 'jeweled' 'jewel-encrusted' 'encrusted' 'fabulous'
  899.  
  900.     verIoOpenWith(actor) = {}
  901.     ioOpenWith(actor, dobj) = {
  902.         dobj.doOpenWith(actor, self);
  903.     }
  904. ;
  905. ming_vase: CCR_treasure_item
  906.     depositpoints = 14
  907.     sdesc = "ming vase"
  908.     ldesc = {
  909.         "It's a delicate, previous, ming vase!";
  910.     }
  911.     location = In_Oriental_Room
  912.     noun = 'vase' 'ming' 'shards' 'pottery'
  913.  
  914.     doDrop(actor) = {
  915.         if (velvet_pillow.isIn(Me.location)) {
  916.             "The vase is now resting, delicately, on a 
  917.             velvet pillow.";
  918.  
  919.             self.moveInto(Me.location);
  920.             
  921.             self.checkpoints;    // make sure we count points
  922.                         // for putting this in building
  923.         }
  924.         else {
  925.             "The ming vase drops with a delicate crash.";
  926.             self.shatter;
  927.         }
  928.     }
  929.  
  930.     verIoPutIn(actor) = {}
  931.     ioPutIn(actor, dobj) = {
  932.         if (dobj = Stream or dobj = Oil) {
  933.             "The sudden change in temperature has 
  934.             delicately shattered the vase.";
  935.  
  936.             self.shatter;
  937.         }
  938.         else {
  939.             "I'm not sure how to do that.";
  940.         }
  941.     }
  942.  
  943.     verDoFill(actor) = {}
  944.     doFill(actor) = {
  945.         if (self.isIn(Stream.location))
  946.             self.ioPutIn(actor, Stream);
  947.         else if (self.isIn(Oil.location))
  948.             self.ioPutIn(actor, Oil);
  949.         else
  950.             "There is nothing here with which to fill the 
  951.             vase.";
  952.     }
  953.  
  954.     verDoBreak(actor) = {}
  955.     doBreak(actor) = {
  956.         "You have taken the vase and hurled it delicately to 
  957.         the ground.";
  958.  
  959.         self.shatter;
  960.     }
  961.  
  962.     shatter = {
  963.         self.moveInto(nil);
  964.         shards.moveInto(Me.location);
  965.     }
  966. ;
  967. shards: CCR_item
  968.     sdesc = "some worthless shards of pottery"
  969.     adesc = { self.sdesc; }
  970.     ldesc = {
  971.         "They're just worthless shards of pottery"; 
  972.  
  973.         if (self.location = Me.location)    // not in a container
  974.             ", littered everywhere.";
  975.         else
  976.             ".";
  977.  
  978.         " They look to be the remains of what was once a
  979.         beautiful vase.  I guess some oaf must have dropped it.";
  980.     }
  981.  
  982.     noun = 'pottery' 'shards'
  983.     adjective = 'worthless'
  984. ;
  985.  
  986. egg_sized_emerald: CCR_treasure_item
  987.     depositpoints = 14
  988.     sdesc = "emerald the size of a plover's egg"
  989.     adesc = { "an "; self.sdesc; }
  990.     ldesc = "Plover's eggs, by the way, are quite large."
  991.     location = In_Plover_Room
  992.     noun = 'emerald'
  993.     adjective = 'egg-sized'
  994. ;
  995. platinum_pyramid: CCR_treasure_item
  996.     depositpoints = 14
  997.     sdesc = "platinum pyramid"
  998.     ldesc = "The platinum pyramid is 8 inches on a side!"
  999.     location = In_Dark_Room
  1000.     noun = 'platinum' 'pyramid'
  1001.     adjective = 'platinum' 'pyramidal'
  1002. ;
  1003. pearl: CCR_treasure_item
  1004.     depositpoints = 14
  1005.     sdesc = "glistening pearl"
  1006.     ldesc = "It's incredibly large!"
  1007.     location = nil
  1008.     noun = 'pearl'
  1009.     adjective = 'glistening' 'incredible' 'incredibly' 'large'
  1010. ;
  1011. persian_rug: CCR_treasure_item
  1012.     depositpoints = 14
  1013.     sdesc = {
  1014.         "Persian rug";
  1015.  
  1016.         if (self.isIn(Dragon.location))
  1017.             " (upon which the dragon is sprawled out)";
  1018.     }
  1019.     adesc = {
  1020.         "a "; self.sdesc; 
  1021.     }
  1022.     ldesc = {
  1023.         if (self.isIn(Dragon.location))
  1024.             "The dragon is sprawled out on the Persian rug!!";
  1025.         else if (not self.isIn(Me))
  1026.             "The Persian rug is spread out on the floor here.";
  1027.         else
  1028.             "The Persian rug is the finest you've ever seen!";
  1029.     }
  1030.     location = In_Secret_Canyon
  1031.     noun = 'rug' 'persian'
  1032.     adjective = 'persian' 'fine' 'finest' 'dragon\'s'
  1033.  
  1034.     verifyRemove(actor) = {
  1035.         if (self.isIn(Dragon.location))
  1036.             "You'll need to get the dragon to move first!";
  1037.     }
  1038. ;
  1039. rare_spices: CCR_treasure_item
  1040.     depositpoints = 14
  1041.     sdesc = "rare spices"
  1042.     adesc = { self.sdesc; }
  1043.     ldesc = "They smell wonderfully exotic!"
  1044.     location = In_Chamber_Of_Boulders
  1045.     noun = 'spices' 'spice'
  1046.     adjective = 'rare' 'exotic'
  1047.  
  1048.     verDoSmell(actor) = {}
  1049.     doSmell(actor) = { self.ldesc; }
  1050. ;
  1051. golden_chain: CCR_treasure_item, keyedLockable
  1052.     depositpoints = 14
  1053.     isfixed = {
  1054.         if (self.islocked)
  1055.             return true;
  1056.         else
  1057.             return nil;
  1058.     }
  1059.     isListed = { return not self.isfixed; }
  1060.  
  1061.     mykey = set_of_keys    // pretty handy, those!
  1062.     islocked = true        // locked meaning "locked to the wall."
  1063.     isopen = nil        // need this since we're keyedLockable
  1064.  
  1065.     sdesc = "golden chain"
  1066.     ldesc = {
  1067.         "The chain has thick links of solid gold!";
  1068.  
  1069.         if (self.islocked) {
  1070.             if (Bear.wasreleased)
  1071.                 "It's locked to the wall!";
  1072.             else
  1073.                 " The bear is chained to the wall with it!";
  1074.         }
  1075.     }
  1076.     heredesc = {
  1077.         if (self.isfixed) {
  1078.             P(); I();
  1079.             if (Bear.wasreleased)
  1080.                 "There is a golden chain here, locked 
  1081.                 to the wall.";
  1082.             else
  1083.                 "There is a golden chain here, and a 
  1084.                 large cave bear is locked to the wall 
  1085.                 with it!";
  1086.         }
  1087.     }
  1088.     
  1089.     location = In_Barren_Room
  1090.     noun = 'chain' 'links' 'shackles'
  1091.     adjective = 'solid' 'gold' 'golden' 'thick'
  1092.  
  1093.     verDoLock(actor) = {
  1094.         if (not self.isIn(In_Barren_Room)) {
  1095.             "There is nothing here to which the chain can 
  1096.             be locked.";
  1097.         }
  1098.         else
  1099.             pass verDoLock;
  1100.     }
  1101.     verDoLockWith(actor, io) = {
  1102.         self.verDoLock(actor);    // -> pass verDoLock (OK?)
  1103.         pass verDoLockWith;
  1104.     }
  1105.  
  1106.     verDoUnlock(actor) = {
  1107.         if (not Bear.wasreleased and not Bear.istame) {
  1108.             "There is no way to get past the bear to 
  1109.             unlock the chain, which is probably just as 
  1110.             well.";
  1111.         }
  1112.         else
  1113.             pass verDoUnlock;
  1114.     }
  1115.     verDoUnlockWith(actor, io) = {
  1116.         self.verDoUnlock(actor);
  1117.         pass verDoUnlockWith;
  1118.     }
  1119.  
  1120.     // inherit proper doUnlock from keyedLockable
  1121.     doUnlockWith(actor, io) = {
  1122.         Bear.wasreleased := true;
  1123.         pass doUnlockWith;
  1124.     }
  1125.     
  1126.     verifyRemove(actor) = {
  1127.         if (not Bear.wasreleased) {
  1128.             if (Bear.istame)
  1129.                 "It's locked to the friendly bear.";
  1130.             else
  1131.                 "It's locked to the ferocious bear!";
  1132.         }
  1133.         else if (self.islocked)
  1134.             "The chain is still locked to the wall.";
  1135.     }
  1136. ;
  1137.